package rubik.seqs;

import java.util.ArrayList;
import java.util.Random;

import rubik.EFace;
import rubik.EMove;


public class Sequence {

	private static final String VALID_CHARS = "UDLRFB'";

	protected static Random r = new Random();
	protected static EMove[] moves = EMove.values();

	protected ArrayList<EMove> _moves;
	
	public Sequence(int max_length)
	{
		this._moves = new ArrayList<EMove>();
	}
	
	public Sequence()
	{
		this._moves = new ArrayList<EMove>();
	}
	
	public Sequence(String moves)
	{
		this._moves = parseMoves(moves); 
	}

	public Sequence(Sequence seq) {
		this._moves = new ArrayList<EMove>();
		for (EMove emove: seq._moves)
			this._moves.add(emove);
	}


	public ArrayList<EMove> getMoves() {
		return this._moves;
	}
	
	protected static EMove randomMove() {
		return moves[r.nextInt(moves.length)];
	}
	
	protected static ArrayList<EMove> parseMoves(String moves) {
		ArrayList<EMove> emoves = new ArrayList<EMove>();
		
		char[] seq = moves.toUpperCase().toCharArray();
		for (int i = 0; i < seq.length; i++) {
			if (VALID_CHARS.indexOf(seq[i]) < 0)
				throw new IllegalArgumentException("'"+seq[i]+"' is not a legal character.");
		}
		for (int i = 0; i < seq.length; i++) {
			boolean ccw = false;
			if ((i < seq.length -1) && (seq[i+1] == '\''))
				ccw = true;
			EFace eface = null;
			switch (seq[i]) {
			case 'U': eface = EFace.UP; break;
			case 'D': eface = EFace.DOWN; break;
			case 'L': eface = EFace.LEFT; break;
			case 'R': eface = EFace.RIGHT; break;
			case 'F': eface = EFace.FRONT; break;
			case 'B': eface = EFace.BACK; break;
			case '\'': break;
			}
			if (eface == null)
				continue;
			emoves.add(EMove.getByValues(eface, ccw));
		}
		return emoves;
	}
	
	public void mutate()
	{
		int i = r.nextInt(this._moves.size()+1);
		EMove emove = randomMove();
		if (i == this._moves.size())
			this._moves.add(emove);
		else
			this._moves.set(i, emove);
	}
	
	public String toString()
	{
		if (this._moves.size()==0)
			return "";
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < this._moves.size()-1; i++) {
			sb.append(this._moves.get(i).toString() +",");
		}
		sb.append(this._moves.get(this._moves.size()-1).toString());
		return sb.toString();
	}
	
}
